#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>

void myls_l(char *pathname);

/*
        argc和argv参数在用命令行编译程序时有用。main( int argc, char* argv[], char **env ) 中 
        第一个参数，int型的argc，为整型，用来统计程序运行时发送给main函数的命令行参数的个数，在VS中默认值为1。 
        第二个参数，char*型的argv[]，为字符串数组，用来存放指向的字符串参数的指针数组，每一个元素指向一个参数。各成员含义如下： 
        argv[0] 指向程序运行的全路径名 
        argv[1] 指向在DOS命令行中执行程序名后的第一个字符串 
        argv[2] 指向执行程序名后的第二个字符串 
        argv[3] 指向执行程序名后的第三个字符串 
        argv[argc] 为NULL 
        第三个参数，char**型的env，为字符串数组。env[]的每一个元素都包含ENVVAR=value形式的字符串，其中ENVVAR为环境变量，value为其对应的值。平时使用到的比较少。
*/



int main(int argc, char *argv[])
{
	char buf[1024] = "";												//路径名
	//
    printf("%d\n",argc);

	if(argc == 1)														//没有输入其他参数时，打开当前目录
	{
		getcwd(buf, sizeof(buf));										//获得当前路径
        printf("%s\n",buf);
		myls_l(buf);
	}
	else																//输入要展示的目录
	{
		myls_l(argv[1]);
		int i = 2;
		while(i < argc)
		{
			printf("\n");
			myls_l(argv[i]);
			i++;
		}
	}
	return 0;
}

void myls_l(char *pathname)
{
	DIR *cwd = NULL;													//路径文件指针
	struct dirent *det = NULL;											//记录读到的文件信息
	struct stat statbuf = {0};											//记录文件的属性
	struct passwd *pwd = NULL;											//记录文件所属用户
	struct group *grp = NULL;											//记录文件所属用户组
	struct tm mtm = {0};

	chdir(pathname);													//!非常重要，否则无法获取文件属性
	//printf("%s\n", buf);												//输出当前路径
	cwd = opendir(pathname);											//打开目录
	while(NULL != (det = readdir(cwd)))									//遍历当前目录
	{
		if(strncmp(det->d_name, ".", 1))
		{
			stat(det->d_name, &statbuf);
			//st_mode													//文件类型
			if(S_ISREG(statbuf.st_mode))
				printf("-");
			else if(S_ISDIR(statbuf.st_mode))
				printf("d");
			else if(S_ISCHR(statbuf.st_mode))
				printf("c");
			else if(S_ISBLK(statbuf.st_mode))
				printf("b");
			else if(S_ISFIFO(statbuf.st_mode))
				printf("p");
			else if(S_ISLNK(statbuf.st_mode))
				printf("l");
			else if(S_ISSOCK(statbuf.st_mode))
				printf("s");
			//st_mode													//文件权限
			if(statbuf.st_mode & S_IRUSR)
				printf("r");
			else
				printf("-");
			if(statbuf.st_mode & S_IWUSR)
				printf("w");
			else
				printf("-");
			if(statbuf.st_mode & S_IXUSR)
				printf("x");
			else
				printf("-");

			if(statbuf.st_mode & S_IRGRP)
				printf("r");
			else
				printf("-");
			if(statbuf.st_mode & S_IWGRP)
				printf("w");
			else
				printf("-");
			if(statbuf.st_mode & S_IXGRP)
				printf("x");
			else
				printf("-");

			if(statbuf.st_mode & S_IROTH)
				printf("r");
			else
				printf("-");
			if(statbuf.st_mode & S_IWOTH)
				printf("w");
			else			
				printf("-");
			if(statbuf.st_mode & S_IXOTH)
				printf("x");
			else
				printf("-");
			//st_nlink													//硬链接数
			printf("%2ld ", statbuf.st_nlink);
			//st_uid													//属主
			pwd = getpwuid(statbuf.st_uid);
			printf("%s ", pwd->pw_name);
			//st_gid													//属组
			grp = getgrgid(statbuf.st_gid);
			printf("%s ", grp->gr_name);
			//st_size													//文件大小
			printf("%5ld ", statbuf.st_size);
			//st_mtim													//最后修改时间
			localtime_r(&(statbuf.st_mtime), &mtm);

            printf("%d-%02d-%02d-%02d:%02d  ",mtm.tm_year+1900,mtm.tm_mon+1,mtm.tm_mday,mtm.tm_hour,mtm.tm_min);
			
            /*
            printf("%dmonth", mtm.tm_mon + 1);
			printf("%4d ", mtm.tm_mday);
			printf("%02d:", mtm.tm_hour);
			printf("%02d ", mtm.tm_min);
            */
			//st_name													//文件名
			printf("%s\n", det->d_name);
		}
	}
	closedir(cwd);														//关闭目录
}
